﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tao.OpenGl;
using Tao.FreeGlut;
using System.Diagnostics;
using TWiStEr.Math;

namespace TWiStEr.OpenGL.Utilities {
	public partial class Camera {
		public void SetWindowSize(int width, int height) {
			aspect = width / height;
			Debug.WriteLine(string.Format("->SetWindowSize: {0}x{1} (fs: {2})", windowWidth, windowHeight, IsFullScreen), "Camera");
			if (!IsFullScreen) {
				windowWidth = width;
				windowHeight = height;
				IsChanged = true;
			}
			Debug.WriteLine(string.Format("<-SetWindowSize: {0}x{1} (fs: {2})", windowWidth, windowHeight, IsFullScreen), "Camera");
		}
		// This function let you control the camera with the mouse
		private bool ___skipNextFollow = false;
		public void FollowMouse(int deltaX, int deltaY) {
			if (___skipNextFollow) { ___skipNextFollow = false; return; }
			if (IsLockedAtCenterPosition) {
				View = AlwaysLookAtCenter.Value;
				Position.Y += deltaY / -6.0f;
				rotatePosd(0, deltaX / -6.0f, 0);
			} else {
				View.Y += deltaY;
				rotateViewd(0, deltaX / -6.0f, 0);
			}
			IsChanged = true;
			if (CaptureMouse) {
				___skipNextFollow = true; // skip the jump to the window center
				Glut.glutWarpPointer(windowWidth >> 1, windowHeight >> 1);
			}
		}
		public void move(double speed, bool sideway) {
			/*
			pos+up
			   |-\
			   |  -\
			   |	-\
			pos*-----view
			 to go forward calculate view - pos,
				which is the vector pointing from pos to view
			 to go sideway calculate the normal(*) of the surface shown above
			*/
			Vector fw = sideway ? Vector.Normal(Position, View, Position + Up) : Vector.Normalize(View - Position);
			fw *= speed;
			Position += fw;
			if (IsLockedAtCenterPosition)
				View = AlwaysLookAtCenter.Value;
			else
				View += fw;
			IsChanged = true;
		} // false
		public void MoveVertical(double yDelta) { // TODO: replace with upcoefficient
			Position.Y += yDelta; View.Y += yDelta; IsChanged = true;
		}
		private void setVerticalSensitivity(double sens) {
			//pos + (view - norm(pos)) * sensitivity,
			//// but view is 0,0,0 by default, so that it'd be
			//pos + norm(-pos) * sensitivity,
			//// but because length uses squares and then sqrt,
			//// the sign of each coordinate isn't matters:
			//pos + -norm(pos) * sensitivity
			View = Position - Vector.Normalize(Position) * (100.0f / sens);
		}

		protected bool fullScreen;
		public bool IsFullScreen {
			get {
				return fullScreen;
			}
			set {
				fullScreen = value;
				IsChanged = true;
				glutUpdateFullScreen();
			}
		}
		public bool IsWindowed {
			get { return !IsFullScreen; }
			set { IsFullScreen = !value; }
		}
		public void SwitchFullScreen() {
			IsFullScreen = !IsFullScreen;
		}
	}
}
